package com.huqing.icu.rentreport.service.app.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.huqing.icu.base.PagingDto;
import com.huqing.icu.enums.DeleteStatusEnum;
import com.huqing.icu.enums.OpenStatusConstants;
import com.huqing.icu.exceptions.BusinessException;
import com.huqing.icu.protocol.SystemResponseCode;
import com.huqing.icu.rentreport.dao.ReportRecordDao;
import com.huqing.icu.rentreport.dto.ReportRecordDto;
import com.huqing.icu.rentreport.dto.ReportRecordQueryDto;
import com.huqing.icu.rentreport.dto.ReportTypeConfigQueryDto;
import com.huqing.icu.rentreport.enums.ReportApproveStatusEnum;
import com.huqing.icu.rentreport.enums.ReportRecordBusTypeEnum;
import com.huqing.icu.rentreport.enums.ReportRecordSourceType;
import com.huqing.icu.rentreport.inout.in.app.ReportRecordAddReq;
import com.huqing.icu.rentreport.inout.in.app.ReportRecordQueryReq;
import com.huqing.icu.rentreport.mapper.ReportRecordMapper;
import com.huqing.icu.rentreport.mapper.ReportTypeConfigMapper;
import com.huqing.icu.rentreport.model.ReportRecord;
import com.huqing.icu.rentreport.model.ReportTypeConfig;
import com.huqing.icu.rentreport.service.app.ReportRecordAddService;
import com.huqing.icu.utils.CopyUtils;
import com.huqing.icu.utils.JsonUtils;
import com.huqing.icu.utils.PageUtils;
import com.huqing.icu.utils.ParamValidateUtils;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 举报记录实现类
 *
 * @author huqing
 * @date 2024-11-19 21:39
 */
@Service
public class ReportAddServiceImpl extends ServiceImpl<ReportRecordMapper, ReportRecord> implements ReportRecordAddService {

    @Autowired
    private ReportRecordDao reportRecordDao;
    /*@Autowired
    private RemoteCommentFeign commentFeign;*/
    @Resource
    private ReportTypeConfigMapper reportTypeConfigMapper;

    //创建一个本地缓存，初始化容量为1024，缓存5分钟移除
    private final Cache<String, String> reportTypeConfigCache = Caffeine.newBuilder().initialCapacity(1024)
            .expireAfterAccess(5L, TimeUnit.MINUTES).build();


    /**
     * 查询举报记录
     *
     * @param queryReq
     * @return
     */
    @Override
    public PagingDto<ReportRecord> queryList(ReportRecordQueryReq queryReq) {

        if (queryReq == null) {
            ParamValidateUtils.throwInternalErrorExp("参数不能为空");
        }
        int startIndex = PageUtils.getPageStartIndex(queryReq.getPageIndex(), queryReq.getPageSize());


        ReportRecordQueryDto queryDto = CopyUtils.copy(queryReq, ReportRecordQueryDto.class);

        //1 isDeleted=0表示已撤销 已撤销的也需要展示出来
        //queryDto.setIsDeleted(0);
        queryDto.setStartIndex(startIndex);
        Integer count = reportRecordDao.getNumByCondition(queryDto);
        if (count == 0) {
            return new PagingDto(Collections.emptyList(), 0, 0);
        }

        //2、查询列表数据
        List<ReportRecordDto> reportRecordList = reportRecordDao.selectByCondition(queryDto);
        PagingDto<ReportRecord> pagingDto = new PagingDto<>(reportRecordList, PageUtils.getTotalPage(count, queryReq.getPageSize()), count);
        return pagingDto;
    }

    /**
     * 新增举报
     *
     * @param addReq
     * @param userId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer addReport(ReportRecordAddReq addReq, Long userId) {
        //1、作者ID(被举报人ID)、业务的创建时间
        Long authorId = null;

        Long commentId = addReq.getCommentId();
        Long busId = addReq.getBusId();

        //不管是举报评论，还是举报业务，都需要检查是否存在
        checkBusExist(commentId, busId, addReq.getBusType());

        //如果证据图不为空，则需要检测证据图是否合规
        if (CollectionUtils.isNotEmpty(addReq.getEvidenceUrlList())) {

        }

        //查询这个评论对应的业务
        String busTitle = "";

        //举报来源的业务时间（如评论时间）
        Timestamp sourceTime = null;

        //4、如果是举报评论，那就是保存评论有关的字段，如果是举报业务本身，比如举报帖子，那就是保存帖子有关的字段
        Long sourceId = commentId == null ? busId : commentId;
        Integer sourceType = commentId == null ? ReportRecordSourceType.THIS.getCode() : ReportRecordSourceType.COMMENT.getCode();

        ReportRecord reportRecord = new ReportRecord();
        reportRecord.setBusId(busId);
        reportRecord.setBusType(addReq.getBusType());
        reportRecord.setSourceId(sourceId);
        reportRecord.setSourceType(sourceType);
        reportRecord.setBusTitle(busTitle);
        reportRecord.setReporterId(userId);
        reportRecord.setToId(addReq.getToId());
        reportRecord.setReportTypeId(addReq.getReportTypeId());
        reportRecord.setReportTypeName(addReq.getReportTypeName());
        reportRecord.setSupplement(addReq.getSupplement());
        reportRecord.setSourceContent(addReq.getSourceContent());
        reportRecord.setSourceImages(addReq.getSourceImages());
        if (CollectionUtils.isNotEmpty(addReq.getEvidenceUrlList())) {
            reportRecord.setEvidenceUrls(JsonUtils.obj2String(addReq.getEvidenceUrlList()));
        }
        reportRecord.setSourceTime(sourceTime);
        reportRecordDao.save(reportRecord);
        return 1;
    }

    /**
     * 撤销举报
     *
     * @param id
     * @param userId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer cancelReport(Long id, Long userId) {
        //1、检查举报记录是否存在，是否为待审核的状态，只能查自己的
        ReportRecord reportRecord = lambdaQuery().eq(ReportRecord::getId, id).eq(ReportRecord::getReporterId, userId)
                .eq(ReportRecord::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getCode()).one();
        if (reportRecord == null) {
            throw new BusinessException(SystemResponseCode.OBJECT_NOT_EXIST.getCode(), "无法找到要撤销的举报记录");
        }
        if (!ReportApproveStatusEnum.PROCESSING.getCode().equals(reportRecord.getApproveStatus())) {
            throw new BusinessException(SystemResponseCode.INTERNAL_ERROR.getCode(), "已经审核，无法撤销");
        }

        //2、将举报记录改成删除状态
        reportRecordDao.deleteById(id);
        return 1;
    }

    /**
     * 查询举报配置
     *
     * @param busType
     * @param applyScene
     * @return
     */
    @Override
    public List<ReportTypeConfig> queryReportConfig(Integer busType, Integer applyScene) {

        //从本地缓存中获取配置
        String result = reportTypeConfigCache.getIfPresent("report_type_config");
        if (StringUtils.isNotBlank(result)) {
            List<ReportTypeConfig> configList = JsonUtils.getList(result, ReportTypeConfig.class);
            return configList;
        }

        //如果本地缓存中没有，则去数据库查询
        ReportTypeConfigQueryDto queryDto = new ReportTypeConfigQueryDto();
        queryDto.setBusType(busType);
        queryDto.setApplyScene(applyScene);
        queryDto.setStatus(OpenStatusConstants.OPEN.getCode());
        queryDto.setIsDeleted(DeleteStatusEnum.NOT_DELETED.getCode());
        List<ReportTypeConfig> reportTypeConfigs = reportTypeConfigMapper.selectByCondition(queryDto);
        return reportTypeConfigs;
    }

    public void checkBusExist(Long commentId, Long busId, Integer busType) {
        //如果是评论，则检查评论是否存在
        if (commentId != null && ReportRecordBusTypeEnum.COMMENT.getCode().equals(busType)) {
            //String commentById = commentFeign.getCommentById(commentId);
        }

        //如果是房源，则检查房源是否存在
        if (ReportRecordBusTypeEnum.HOUSE.getCode().equals(busType)) {

        }

        //如果是社区帖子，则检查帖子是否存在
        if (ReportRecordBusTypeEnum.COMMUNITY_POST.getCode().equals(busType)) {

        }
    }
}
